#include "ComponentsTreeModel.h"
#include "ComponentTreeItem.h"

#include "common.h"

#include <QRegExp>
#include <QMessageBox>

ComponentsTreeModel::ComponentsTreeModel(QObject* parent)
    :super(parent)
{
}

ComponentsTreeModel::ComponentsTreeModel(const QString &data, QObject *parent)
    :super(parent)
{
    QList<QVariant> rootData;
    rootData << "Components" << "Description" << "Example";
    rootItem = new ComponentTreeItem(rootData);
    setupModelData( data.split(QString("\n")), rootItem );
}

ComponentsTreeModel::ComponentsTreeModel(const QList<Component> &data, QObject *parent) :super(parent)
{
    QList<QVariant> rootData;
    rootData << "Components" << "Description" << "Example";
    rootItem = new ComponentTreeItem(rootData);
    setupModelData(data, rootItem );

}

void ComponentsTreeModel::setupModelData(const QList<Component> &data, ComponentTreeItem *parent)
{
    foreach(Component component, data)
    {
        QList<QVariant> columnData;
        columnData << component.name << component.description << "";

        parent->appendChildItem(new ComponentTreeItem(columnData,parent));
        ComponentTreeItem* current = parent->childItem(parent->childCount()-1);

        foreach(Component::Function function, component.functions)
        {
            columnData.clear();
            columnData << function.name() << function.description() << function.example();

            current->appendChildItem(new ComponentTreeItem(columnData, current));
        }
    }
}

void ComponentsTreeModel::setupModelData(const QStringList& lines, ComponentTreeItem* parent)
{
    QRegExp rx( "(\\w+):\\s+(.*)$" );

    // Предположительно у строк такой формат: "Component1: function1 function2"
    foreach(QString str, lines)
    {
        int position = rx.indexIn(str);

        if(position != -1)
        {
            QStringList functions = rx.cap(2).split(" ",QString::SkipEmptyParts);
            QList<QVariant> columnData;
            foreach (QString function, functions)
            {
                columnData << function;
            }

            parent->appendChildItem(new ComponentTreeItem(columnData,parent));
        }
    }
}

bool ComponentsTreeModel::removeRows(int row, int count, const QModelIndex &parent)
{
    ComponentTreeItem* parentItem;
    if ( !parent.isValid() ) // Т.е это корневой элемент.
        parentItem = rootItem;
    else
        parentItem= static_cast<ComponentTreeItem*>(parent.internalPointer());

    if (row < 0 || count < 0 ||
        row + count > parentItem->childCount())
        return false;
    // Начнём удалять с конца
    for (int i = (count + row - 1); i >= row; i--)
    {
        parentItem->removeChildItem(
                parentItem->childItem(i)
                );
    }
    return true;
}

int ComponentsTreeModel::columnCount(const QModelIndex &parent) const
{
    if(parent.isValid())
        return static_cast<ComponentTreeItem*>(parent.internalPointer())->columnCount();
    else
        return rootItem->columnCount();
}

QVariant ComponentsTreeModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    ComponentTreeItem* item = static_cast<ComponentTreeItem*> (index.internalPointer());
    return item->data(index.column());
}

Qt::ItemFlags ComponentsTreeModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

QVariant ComponentsTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return rootItem->data(section);

    return QVariant();
}

int ComponentsTreeModel::rowCount(const QModelIndex &parent) const
{
    ComponentTreeItem *parentItem;
    if (parent.column() > 0)
        return 0;

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<ComponentTreeItem*>(parent.internalPointer());

    return parentItem->childCount();
}

QModelIndex ComponentsTreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    ComponentTreeItem *childItem = static_cast<ComponentTreeItem*>(index.internalPointer());
    ComponentTreeItem *parentItem = childItem->parent();

    if (parentItem == rootItem)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

QModelIndex ComponentsTreeModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!hasIndex(row, column, parent))
    {
        return QModelIndex();
    }

    ComponentTreeItem *parentItem;

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<ComponentTreeItem*>(parent.internalPointer());

    ComponentTreeItem *childItem = parentItem->childItem(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

ComponentsTreeModel::~ComponentsTreeModel()
{
    //rootItem.clear();
    delete rootItem;
}

